#include "../include/head.h"

int main(int argc, char *argv[])
{
 
    char now_path_buf[512] = {0};

    //连接socket
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(30000);
    int ret=connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");

    //epfd初始化
    int epfd=epoll_create(1);
    epollAdd(epfd,STDIN_FILENO,0);
    epollAdd(epfd,sockfd,0);

    //缓冲区
    char readbuf[4096]={0}; //接收stdin数据

    //客户端是否退出标志
    int is_alive=1; //1活 0死

    struct epoll_event readySet[1024]={0};
    
    // 用于存储用户登录信息
    ResponsePackage* response=(ResponsePackage*)calloc(1,sizeof(ResponsePackage));
    char user_name_buf[256];
    char user_password_buf[256];
    char args_buf[1024];
    fflush(stdin);
    while (1)
    {
        memset(response, 0, sizeof(ResponsePackage));

        bzero(user_name_buf, sizeof(user_name_buf));
        bzero(user_password_buf, sizeof(user_password_buf));

        int tag;
        printf("请选择 1.登录 2.注册\n");
        scanf("%d", &tag);
        if(tag == 1)
        {
            response->type=USER_LOGIN1;
            printf("请输入用户名：\n");
            scanf("%s", user_name_buf);

            // printf("用户名为：%s\n", user_name_buf);
            // printf("正在检测用户名是否存在...\n");

            response->args_len = strlen(user_name_buf);
            memcpy(response->args_val, user_name_buf, response->args_len);
            send(sockfd, &response->type, sizeof(int), MSG_NOSIGNAL);
            send(sockfd, &response->args_len, sizeof(int), MSG_NOSIGNAL);
            send(sockfd, response->args_val, response->args_len, MSG_NOSIGNAL);

            memset(response, 0, sizeof(ResponsePackage));

            int ret = recvn(sockfd, &response->type, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            ret = recvn(sockfd, &response->args_len, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            if(response->args_len != 0)
            {
                ret = recvn(sockfd, response->args_val, response->args_len, NULL);
                if(ret == -1)
                {
                    printf("服务端已断开链接！\n");
                    is_alive = 0;
                    break;
                }
            }
            

            if(response->type == L_R_SUCCESS)
            {
                // printf("用户名检查成功！\n");
            }
            else if(response->type == L_R_ERR)
            {
                printf("登录失败,请重新登录!,失败原因: %s\n", response->args_val);
                continue;
            }

            char setting[30] = {0};
            memcpy(setting, response->args_val, response->args_len);
            // printf("%s\n", setting);

            printf("请输入密码：\n");
            scanf("%s", user_password_buf);

            // 通过返回的盐值计算密码密文
            char *ciphertest = crypt(user_password_buf, setting);

            sprintf(args_buf, "%s %s", user_name_buf,ciphertest);

            memset(response, 0, sizeof(ResponsePackage));

            // 发送用户名和密码密文
            response->type=USER_LOGIN2;
            response->args_len = strlen(args_buf);
            memcpy(response->args_val, args_buf, response->args_len);
            // printf("%s\n", response->args_val);

            send(sockfd, &response->type, sizeof(int), MSG_NOSIGNAL);
            send(sockfd, &response->args_len, sizeof(int), MSG_NOSIGNAL);
            send(sockfd, response->args_val, response->args_len, MSG_NOSIGNAL);

            // 接受服务端对于密码的验证
            memset(response, 0, sizeof(ResponsePackage));

            ret = recvn(sockfd, &response->type, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            ret = recvn(sockfd, &response->args_len, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            if(response->args_len != 0)
            {
                ret = recvn(sockfd, response->args_val, response->args_len, NULL);
                if(ret == -1)
                {
                    printf("服务端已断开链接！\n");
                    is_alive = 0;
                    break;
                }
            }
            if(response->type == L_R_SUCCESS)
            {
                printf("登录成功！MyGO!!!!!\n");
                break;
            }
            else if(response->type == L_R_ERR)
            {
                printf("登录失败,请重新登录!,失败原因: %s\n", response->args_val);
                continue;
            }

        }
        else if(tag == 2)
        {
            response->type=USER_REGI;
            
            printf("请输入用户名：\n");
            scanf("%s", user_name_buf);
            printf("请输入密码：\n");
            scanf("%s", user_password_buf);

            // 生成一个随机盐值
            char setting[30] = {0};
            salt_create(setting);
            char *ciphertest = crypt(user_password_buf, setting);

            // 将用户名、盐值、密文密码拼接
            sprintf(args_buf, "%s %s %s", user_name_buf, setting,ciphertest);
            // printf("拼接后：%s\n", args_buf);

            memcpy(response->args_val, args_buf, strlen(args_buf));


            send(sockfd, &response->type, sizeof(int), MSG_NOSIGNAL);
            response->args_len = strlen(response->args_val);
            // printf("发送的用户名+盐值+密文密码的总长度为：%d\n", response->args_len);
            send(sockfd, &response->args_len, sizeof(int), MSG_NOSIGNAL);
            send(sockfd, response->args_val, response->args_len, MSG_NOSIGNAL);

            memset(response, 0, sizeof(ResponsePackage));

            printf("等待服务端检查...\n");
            // 接受服务端对此次登录/注册请求的检查
            int ret = recvn(sockfd, &response->type, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            ret = recvn(sockfd, &response->args_len, sizeof(int), NULL);
            if(ret == -1)
            {
                printf("服务端已断开链接！\n");
                is_alive = 0;
                break;
            }
            if(response->args_len!=0)
            {
                ret = recvn(sockfd, response->args_val, response->args_len, NULL);
                if(ret == -1)
                {
                    printf("服务端已断开链接！\n");
                    is_alive = 0;
                    break;
                }
            }

            // 检查返回的标志位
            if(response->type == L_R_SUCCESS)
            {
                printf("注册成功！MyGO!!!!!\n");
                break;
            }
            else if(response->type == L_R_ERR)
            {
                printf("登录失败,请重新登录!,失败原因: %s\n", response->args_val);
                continue;
            }
        }
    }

    fflush(stdin);
    
    while (is_alive)
    {
        int num=epoll_wait(epfd,readySet,1024,-1);
        for(int i=0;i<num;i++){
            if(readySet[i].data.fd==STDIN_FILENO)
            {
                bzero(readbuf,sizeof(readbuf));
                int submittype=-100;
                ssize_t sret=read(STDIN_FILENO,readbuf,sizeof(readbuf));
                if (sret == 0)
                {
                    //客户端退出指令
                    is_alive=0;
                    break;
                }
                else
                {
                    //去掉接收到的末尾\n换行符
                    readbuf[strlen(readbuf)-1]='\0';  

                    // 判断用户输入指令是否正确 正确封包 错误等待用户重新输入
                    if(simplejudge(readbuf,&submittype,now_path_buf)==0){
                        submit(sockfd,readbuf,submittype);
                    }
                }

            }
            else if(readySet[i].data.fd==sockfd)
            {
                memset(response, 0, sizeof(ResponsePackage));

                // 对服务端传入的包进行解析
                int ret = recvn(sockfd, &response->type, sizeof(int), NULL);
                if(ret == -1)
                {
                    printf("服务端已断开链接！\n");
                    is_alive = 0;
                    break;
                }

                ret = recvn(sockfd, &response->args_len, sizeof(int), NULL);
                if(ret == -1)
                {
                    printf("服务端已断开链接！\n");
                    is_alive = 0;
                    break;
                }
                if(response->args_len !=0)
                {
                    ret = recvn(sockfd, &response->args_val, response->args_len, NULL);
                    if(ret == -1)
                    {
                        printf("服务端已断开链接！\n");
                        is_alive = 0;
                        break;
                    }
                }
                // printf("已接收%d\n",response->type);
                recv_resolver(response->type,response->args_len,response->args_val,now_path_buf,sockfd);
            }
              
        }
    }
    close(sockfd);
    return 0;
}
